package br.com.sgi.model;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.hibernate.annotations.Type;

import br.com.sgi.enuns.TipoAdmissaoEnum;
import br.com.sgi.enuns.TipoConsagracaoMinisterialEnum;
import br.com.sgi.util.ICombobox;

@Entity
@Table(name = "MEMBRO")
@NamedQueries( {
		@NamedQuery(name = "buscarClienteByParans", query = "SELECT n FROM Membro n "
				+ "WHERE lower(n.nome) like:nome"),
		@NamedQuery(name = "buscarMembroPorFiltros", query = "\n SELECT m FROM Membro m "
				+ "\n WHERE m.igrejaPertence.sistema.coSeqSistema =:coSistema"
				+ "\n AND (m.igrejaPertence.coSeqIgreja = :coIgreja OR m.igrejaPertence.coSeqIgreja in(SELECT ui.igreja.coSeqIgreja from UsersIgreja ui WHERE ui.users.username= :username)) "
				+ "\n AND ('' = :nome or m.nome like :nome)"
				+ "\n AND ('' = :coMembroVazio or m.coSeqMembro = :coMembro)"
				+ "\n AND (null = :dtNascimento or m.dtNascimento = :dtNascimento)"
				+ " order by m.nome"),
		@NamedQuery(name = "buscarAniversariantesMes", query = "\n SELECT m FROM Membro m "
				+ "\n WHERE m.igrejaPertence.sistema.coSeqSistema =:coSistema"
				+ "\n AND (m.igrejaPertence.coSeqIgreja = :coIgreja OR m.igrejaPertence.coSeqIgreja in(SELECT ui.igreja.coSeqIgreja from UsersIgreja ui WHERE ui.users.username= :username)) "
				+ "\n AND  Extract(Month From dt_nascimento) = Extract(Month From Now())"
				+ "\n AND  m.email != '' )"
				+ "order by m.dtNascimento "),
		@NamedQuery(name = "buscarAniversariantesDia", query = "\n SELECT m FROM Membro m "
				+ "\n WHERE m.igrejaPertence.sistema.coSeqSistema =:coSistema"
				+ "\n AND (m.igrejaPertence.coSeqIgreja = :coIgreja OR m.igrejaPertence.coSeqIgreja in(SELECT ui.igreja.coSeqIgreja from UsersIgreja ui WHERE ui.users.username= :username)) "
				+ "\n AND  Extract(Day From dt_nascimento) = Extract(Day From Now()) "
				+ "\n AND  Extract(Month From dt_nascimento) = Extract(Month From Now()) "
				+ "\n AND  m.email != '' )"
				+ " order by m.nome"),
		@NamedQuery(name = "buscarTodosMembrosPorUsers", query = " SELECT m FROM Membro m "
				+ " WHERE m.igrejaPertence.sistema.coSeqSistema =:coSistema"
				+ " AND (m.igrejaPertence.coSeqIgreja = :coIgreja OR m.igrejaPertence.coSeqIgreja in(SELECT ui.igreja.coSeqIgreja from UsersIgreja ui WHERE ui.users.username= :username)) "
				+ " order by m.nome")
// @NamedQuery(
// name="buscarMembroPorId",
// query=" SELECT m FROM Membro m " +
// " WHERE m.igrejaFrequencia.sistema.coSeqSistema =:coSistema" +
// " AND m.coSeqMembro = :coSeqMembro" ),
})
public class Membro implements ICombobox {

	private static final long serialVersionUID = 1L;

	@Id
	@Column(name = "CO_SEQ_MEMBRO")
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seq_membro_seqmembro")
	@SequenceGenerator(name = "seq_membro_seqmembro", sequenceName = "SGI.seq_membro", allocationSize=1)
	private Long coSeqMembro;

	@NotNull
	@Size(max = 100)
	private String nome;

	@Column(name = "dt_NASCIMENTO")
	@NotNull
	private Date dtNascimento;

	@NotNull
	@Size(max = 2)
	private String sexo;

	@Column(name = "ESTADO_CIVIL")
	@NotNull
	@Size(max = 15)
	private String estadoCivil;

	@Size(max = 100)
	private String logradouro;

	private Integer numero;

	@Size(max = 100)
	private String complemento;

	@Size(max = 100)
	private String bairro;

	@Size(max = 60)
	private String cidade;

	@Size(max = 2)
	private String uf;

	@Size(max = 25)
	private String cep;

	@Size(max = 100)
	private String naturalidade;

	@Column(name = "UF_NATURALIDADE")
	@Size(max = 2)
	private String ufNaturalidade;

	@Size(max = 30)
	private String nascionalidade;

	@Size(max = 15)
	private String rg;

	@Size(max = 14)
	private String cpf;

	@Column(name = "TELEFONE", length = 25)
	private String telefone;

	@Size(max = 25)
	private String celular;

	@Column(name = "TELEFONE_EMPRESA")
	@Size(max = 25)
	private String telefoneEmpresa;

	@Size(max = 100)
	private String email;

	@Column(name = "GRAU_INSTRUCAO")
	private String grauDeInstrucao;

	@Size(max = 100)
	private String profissao;

	@Column(name = "TIPO_SANGUINEO")
	@Size(max = 3)
	private String tipoSanguineo;

	@Column(name = "foto")
	private byte[] foto;

	// Dados familiares

	@Column(name = "NO_PAI")
	@Size(max = 100)
	private String noPai;

	@Column(name = "NO_MAE")
	@Size(max = 100)
	private String noMae;

	@Column(name = "DT_CASAMENTO")
	private Date dtCasamento;

	@Column(name = "NO_CONJUGE")
	@Size(max = 100)
	private String noConjuge;

	@Column(name = "NU_FILHOS")
	private Long nuFilhos;

	// Dados ministeriais

	// Dados Transferencia
	@Column(name = "TIPO_ADIMISSAO")
	@Type(type = "br.com.sgi.type.TipoAdmissaoType")
	private TipoAdmissaoEnum tipoAdmissao;

	@Size(max = 60)
	@Column(name = "LOCAL_BATISMO", length = 60)
	private String localBatismo;

	@Column(name = "PR_OFICIANTE", length = 100)
	@Size(max = 100)
	private String prOficiante;

	@Column(name = "NO_IGREJA_TRANSF", length = 100)
	@Size(max = 100)
	private String noIgrejaTransferencia;

	@Column(name = "MEMBRO_FUNCAO_ANTERIOR", length = 100)
	private String membroFuncaoAnterior;

	@Column(name = "CONSAGRACAO_MINISTERIAL_ANTES")
	@Size(max = 100)
	private String consagracaoMinisterialAntes;

	@Column(name = "DT_CONS_MINISTERIAL_ANTES")
	private Date dtConsMinisterialAntes;

	@Column(name = "INATIVO", length = 1)
	@Type(type = "br.com.sgi.type.SimNaoType")
	private Boolean inativo;

	// Dados conversao

	@Column(name = "DT_CONVERSAO")
	private Date dtConversao;

	@Column(name = "DT_BATISMO")
	private Date dtBatismo;

	@Column(name = "CONSAGRACAO_MINISTERIAL")
	@Type(type = "br.com.sgi.type.TipoConsagracaoType")
	private TipoConsagracaoMinisterialEnum consagracaoMinisterial;

	@Column(name = "DT_CONS_MINIST")
	private Date dtConsagracaoMinist;

	@ManyToOne
	@NotNull
	@JoinColumn(name = "CO_IGREJA")
	private Igreja igrejaPertence;

	// @OneToMany(mappedBy="membro", fetch = FetchType.EAGER,
	// cascade={CascadeType.ALL})
	@OneToMany(mappedBy = "membro", cascade = { CascadeType.MERGE, CascadeType.REMOVE,
			CascadeType.REFRESH }, fetch = FetchType.EAGER)
	private List<MembroFuncao> membroFuncaoAtual;

	// @OneToMany(mappedBy="membro", cascade={CascadeType.ALL})
	@OneToMany(mappedBy = "membro", cascade = { CascadeType.MERGE, CascadeType.REMOVE,
			CascadeType.REFRESH }, fetch = FetchType.EAGER)
	private List<MembroFuncao> membroFuncaoPretendida;

	// Dados gerais
	@Column(name = "ORIGEM_RELIGIOSA")
	@Size(max = 2)
	private String origemReligiosa;

	@Column(name = "OBSERVACAO")
	@Size(max = 2000)
	private String observacao;

	@Column(name = "DT_ADMISSAO")
	private Date dtAdmissao;

	@Column(name = "DT_CADASTRO", length = 8)
	private Date dtCadastro;

	@Column(name = "DT_ATUALIZACAO", length = 8)
	private Date dtAtualizacao;

	@Transient
	private boolean existeConsagracaoAntes;

	@Transient
	private String matricula;

	@Transient
	private boolean selecionado;

	@Transient
	private String status;

	public Membro() {

	}

	public Membro(String nome, Date dtNascimento) {
		this.nome = nome;
		this.dtNascimento = dtNascimento;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		Membro other = (Membro) obj;
		if (coSeqMembro == null) {
			if (other.coSeqMembro != null) {
				return false;
			}
		} else if (!coSeqMembro.equals(other.coSeqMembro)) {
			return false;
		}
		return true;
	}

	public String getBairro() {
		return bairro;
	}

	public String getCelular() {
		return celular;
	}

	public String getCep() {
		return cep;
	}

	public String getCidade() {
		return cidade;
	}

	public String getComplemento() {
		return complemento;
	}

	public TipoConsagracaoMinisterialEnum getConsagracaoMinisterial() {
		return consagracaoMinisterial;
	}

	public String getConsagracaoMinisterialAntes() {
		return consagracaoMinisterialAntes;
	}

	public Long getCoSeqMembro() {
		return coSeqMembro;
	}

	public String getCpf() {
		return cpf;
	}

	public Date getDtAdmissao() {
		return dtAdmissao;
	}

	public Date getDtAtualizacao() {
		return dtAtualizacao;
	}

	public Date getDtBatismo() {
		return dtBatismo;
	}

	public Date getDtCadastro() {
		return dtCadastro;
	}

	public Date getDtCasamento() {
		return dtCasamento;
	}

	public Date getDtConsagracaoMinist() {
		return dtConsagracaoMinist;
	}

	public Date getDtConsMinisterialAntes() {
		return dtConsMinisterialAntes;
	}

	public Date getDtConversao() {
		return dtConversao;
	}

	public Date getDtNascimento() {
		return dtNascimento;
	}

	public String getEmail() {
		return email;
	}

	public String getEstadoCivil() {
		return estadoCivil;
	}

	public byte[] getFoto() {
		return foto;
	}

	public String getGrauDeInstrucao() {
		return grauDeInstrucao;
	}

	public Igreja getIgrejaPertence() {
		return igrejaPertence;
	}

	public Boolean getInativo() {
		return inativo;
	}

	public String getLocalBatismo() {
		return localBatismo;
	}

	public String getLogradouro() {
		return logradouro;
	}

	public String getMatricula() {
		return matricula;
	}

	public String getMembroFuncaoAnterior() {
		return membroFuncaoAnterior;
	}

	public List<MembroFuncao> getMembroFuncaoAtual() {
		return membroFuncaoAtual;
	}

	public List<MembroFuncao> getMembroFuncaoPretendida() {
		return membroFuncaoPretendida;
	}

	public String getNascionalidade() {
		return nascionalidade;
	}

	public String getNaturalidade() {
		return naturalidade;
	}

	public String getNoConjuge() {
		return noConjuge;
	}

	public String getNoIgrejaTransferencia() {
		return noIgrejaTransferencia;
	}

	public String getNoMae() {
		return noMae;
	}

	public String getNome() {
		return nome;
	}

	public String getNoPai() {
		return noPai;
	}

	public Long getNuFilhos() {
		return nuFilhos;
	}

	public Integer getNumero() {
		return numero;
	}

	public String getObservacao() {
		return observacao;
	}

	public String getOrigemReligiosa() {
		return origemReligiosa;
	}

	public String getPrOficiante() {
		return prOficiante;
	}

	public String getProfissao() {
		return profissao;
	}

	public String getRg() {
		return rg;
	}

	public String getSexo() {
		return sexo;
	}

	public String getStatus() {
		if (inativo == null || inativo) {
			return "Inativo";
		} else {
			return "Ativo";
		}

	}

	public String getTelefone() {
		return telefone;
	}

	public String getTelefoneEmpresa() {
		return telefoneEmpresa;
	}

	public TipoAdmissaoEnum getTipoAdmissao() {
		return tipoAdmissao;
	}

	public String getTipoSanguineo() {
		return tipoSanguineo;
	}

	public String getUf() {
		return uf;
	}

	public String getUfNaturalidade() {
		return ufNaturalidade;
	}

	@Override
	public Object getValue() {

		return getNome();
	}

	// public String getTipoAdmissao() {
	// return tipoAdmissao;
	// }
	//
	// public void setTipoAdmissao(String tipoAdmissao) {
	// this.tipoAdmissao = tipoAdmissao;
	// }

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((coSeqMembro == null) ? 0 : coSeqMembro.hashCode());
		return result;
	}

	public boolean isExisteConsagracaoAntes() {
		if (consagracaoMinisterialAntes != null && !consagracaoMinisterialAntes.isEmpty()) {
			existeConsagracaoAntes = true;
		}

		return existeConsagracaoAntes;
	}

	public boolean isSelecionado() {
		return selecionado;
	}

	public void setBairro(String bairro) {
		this.bairro = bairro;
	}

	public void setCelular(String celular) {
		this.celular = celular;
	}

	public void setCep(String cep) {
		this.cep = cep;
	}

	public void setCidade(String cidade) {
		this.cidade = cidade;
	}

	public void setComplemento(String complemento) {
		this.complemento = complemento;
	}

	public void setConsagracaoMinisterial(TipoConsagracaoMinisterialEnum consagracaoMinisterial) {
		this.consagracaoMinisterial = consagracaoMinisterial;
	}

	public void setConsagracaoMinisterialAntes(String consagracaoMinisterialAntes) {
		this.consagracaoMinisterialAntes = consagracaoMinisterialAntes;
	}

	public void setCoSeqMembro(Long coSeqMembro) {
		this.coSeqMembro = coSeqMembro;
	}

	public void setCpf(String cpf) {
		this.cpf = cpf;
	}

	public void setDtAdmissao(Date dtAdmissao) {
		this.dtAdmissao = dtAdmissao;
	}

	public void setDtAtualizacao(Date dtAtualizacao) {
		this.dtAtualizacao = dtAtualizacao;
	}

	public void setDtBatismo(Date dtBatismo) {
		this.dtBatismo = dtBatismo;
	}

	public void setDtCadastro(Date dtCadastro) {
		this.dtCadastro = dtCadastro;
	}

	public void setDtCasamento(Date dtCasamento) {
		this.dtCasamento = dtCasamento;
	}

	public void setDtConsagracaoMinist(Date dtConsagracaoMinist) {
		this.dtConsagracaoMinist = dtConsagracaoMinist;
	}

	public void setDtConsMinisterialAntes(Date dtConsMinisterialAntes) {
		this.dtConsMinisterialAntes = dtConsMinisterialAntes;
	}

	public void setDtConversao(Date dtConversao) {
		this.dtConversao = dtConversao;
	}

	public void setDtNascimento(Date dtNascimento) {
		this.dtNascimento = dtNascimento;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setEstadoCivil(String estadoCivil) {
		this.estadoCivil = estadoCivil;
	}

	public void setExisteConsagracaoAntes(boolean existeConsagracaoAntes) {
		consagracaoMinisterialAntes = "";
		dtConsMinisterialAntes = null;
		this.existeConsagracaoAntes = existeConsagracaoAntes;
	}

	public void setFoto(byte[] foto) {
		this.foto = foto;
	}

	public void setGrauDeInstrucao(String grauDeInstrucao) {
		this.grauDeInstrucao = grauDeInstrucao;
	}

	public void setIgrejaPertence(Igreja igrejaPertence) {
		this.igrejaPertence = igrejaPertence;
	}

	public void setInativo(Boolean inativo) {
		this.inativo = inativo;
	}

	public void setLocalBatismo(String localBatismo) {
		this.localBatismo = localBatismo;
	}

	public void setLogradouro(String logradouro) {
		this.logradouro = logradouro;
	}

	public void setMatricula(String matricula) {
		this.matricula = matricula;
	}

	public void setMembroFuncaoAnterior(String membroFuncaoAnterior) {
		this.membroFuncaoAnterior = membroFuncaoAnterior;
	}

	public void setMembroFuncaoAtual(List<MembroFuncao> membroFuncaoAtual) {
		this.membroFuncaoAtual = membroFuncaoAtual;
	}

	public void setMembroFuncaoPretendida(List<MembroFuncao> membroFuncaoPretendida) {
		this.membroFuncaoPretendida = membroFuncaoPretendida;
	}

	public void setNascionalidade(String nascionalidade) {
		this.nascionalidade = nascionalidade;
	}

	public void setNaturalidade(String naturalidade) {
		this.naturalidade = naturalidade;
	}

	public void setNoConjuge(String noConjuge) {
		this.noConjuge = noConjuge;
	}

	public void setNoIgrejaTransferencia(String noIgrejaTransferencia) {
		this.noIgrejaTransferencia = noIgrejaTransferencia;
	}

	public void setNoMae(String noMae) {
		this.noMae = noMae;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public void setNoPai(String noPai) {
		this.noPai = noPai;
	}

	public void setNuFilhos(Long nuFilhos) {
		this.nuFilhos = nuFilhos;
	}

	public void setNumero(Integer numero) {
		this.numero = numero;
	}

	public void setObservacao(String observacao) {
		this.observacao = observacao;
	}

	public void setOrigemReligiosa(String origemReligiosa) {
		this.origemReligiosa = origemReligiosa;
	}

	public void setPrOficiante(String prOficiante) {
		this.prOficiante = prOficiante;
	}

	public void setProfissao(String profissao) {
		this.profissao = profissao;
	}

	public void setRg(String rg) {
		this.rg = rg;
	}

	public void setSelecionado(boolean selecionado) {
		this.selecionado = selecionado;
	}

	public void setSexo(String sexo) {
		this.sexo = sexo;
	}

	/**
	 * @param status
	 *            the status to set
	 */
	public void setStatus(String status) {
		this.status = status;
	}

	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}

	public void setTelefoneEmpresa(String telefoneEmpresa) {
		this.telefoneEmpresa = telefoneEmpresa;
	}

	public void setTipoAdmissao(TipoAdmissaoEnum tipoAdmissao) {
		this.tipoAdmissao = tipoAdmissao;
	}

	public void setTipoSanguineo(String tipoSanguineo) {
		this.tipoSanguineo = tipoSanguineo;
	}

	public void setUf(String uf) {
		this.uf = uf;
	}

	public void setUfNaturalidade(String ufNaturalidade) {
		this.ufNaturalidade = ufNaturalidade;
	}

}
